package com.yuntu.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuntu.annotation.AuthCheck;
import com.yuntu.common.BaseResponse;
import com.yuntu.common.DeleteRequest;
import com.yuntu.common.ResultUtils;
import com.yuntu.demo.constant.UserConstant;
import com.yuntu.demo.dto.user.*;
import com.yuntu.demo.entity.User;
import com.yuntu.demo.vo.LoginUserVO;
import com.yuntu.demo.vo.UserVO;
import com.yuntu.exception.ErrorCode;
import com.yuntu.exception.ThrowUtils;
import com.yuntu.exception.bizException;
import com.yuntu.mapper.UserMapper;
import com.yuntu.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author k
 * @since 2025-03-19
 */
@RestController
@RequestMapping("/user")
@Api("用户接口")
public class UserController {
    @Resource
    IUserService userService;
    @Resource
    UserMapper userMapper;
    @Resource
    RedisTemplate redisTemplate;
    @PostMapping("register")
    @ApiOperation("注册")
    public BaseResponse<Long> register(@RequestBody UserRegisterRequest user) {
        ThrowUtils.throwIf(user==null,new bizException(-4,"未写入注册数据"));
        ThrowUtils.throwIf(user.getPhone()==null,new bizException(-1,"手机号未填写"));
        ThrowUtils.throwIf(user.getCheckCode()==null,new bizException(-1,"未填写验证码"));
        long result = userService.register(user);
        return ResultUtils.success(result);
    }
    @PostMapping("login")
    @ApiOperation("登录")
    public BaseResponse<LoginUserVO> login(@RequestBody UserLoginRequest user, HttpSession session) {
        LoginUserVO userVO=userService.login(user,session);
        return ResultUtils.success(userVO);
    }
    @GetMapping("/get/login")
    @ApiOperation("获取用户信息")
    public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request) {
        LoginUserVO user = userService.getLoginUser(request);
        return ResultUtils.success(user);
    }

    @PostMapping("logout")
    @ApiOperation("注销")
    public BaseResponse logout(HttpSession session) {
        Object user = session.getAttribute(UserConstant.USER_LOGIN_STATE);
        ThrowUtils.throwIf(user==null,new bizException(-1,"用户未登录"));
        session.removeAttribute(UserConstant.USER_LOGIN_STATE);
        return ResultUtils.success(null);
    }

    @PostMapping("add")
    @ApiOperation("增加用户")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> add(@RequestBody UserAddRequest user) {
        ThrowUtils.throwIf(user==null,ErrorCode.NOT_FOUND_ERROR);
        User addUser=new User();
        BeanUtils.copyProperties(user,addUser);
        //设置默认密码
        addUser.setUserPassword(userService.getPwd("12345678"));
        //账户是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount, user.getUserAccount());
        User reuser = userMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(reuser!=null,new bizException(-2,"账号已经存在"));
        //存入数据库
        boolean save = userService.save(addUser);
        ThrowUtils.throwIf(!save,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(addUser.getId());
    }

    @PostMapping("get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation("管理员获取用户信息")
    public BaseResponse<User> getUserByid(long id) {
        ThrowUtils.throwIf(id<=0,ErrorCode.PARAMS_ERROR);
        User user=userService.getById(id);
        ThrowUtils.throwIf(user==null,new bizException(-1,"该用户不存在"));
        return ResultUtils.success(user);
    }
    @PostMapping("get/vo")
    @ApiOperation("查找用户")
    public BaseResponse<UserVO> getUserVoById(long id) {
        BaseResponse<User> userByid = getUserByid(id);
        User data = userByid.getData();
        return ResultUtils.success(userService.getUserVO(data));
    }
    @PostMapping("delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation("删除用户")
    public BaseResponse<Boolean> deleteById(@RequestBody DeleteRequest deleteRequest) {
        ThrowUtils.throwIf(deleteRequest==null||deleteRequest.getId()<=0,ErrorCode.PARAMS_ERROR);
        boolean b = userService.removeById(deleteRequest.getId());
        ThrowUtils.throwIf(!b,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }
    @PostMapping("update")
    @ApiOperation("修改用户")
    public BaseResponse<Boolean> updateUserById(@RequestBody UserUpdateRequest user) {
        ThrowUtils.throwIf(user==null,ErrorCode.PARAMS_ERROR);
        User updateUser=new User();
        BeanUtils.copyProperties(user,updateUser);
        boolean b = userService.updateById(updateUser);
        ThrowUtils.throwIf(!b,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }
    @PostMapping("update/phone")
    @ApiOperation("修改用户电话")
    public BaseResponse<Boolean> updatePhoneById(@RequestBody UpdatePhoneRequest updatePhoneRequest){
        String code = updatePhoneRequest.getCode();
        String phone = updatePhoneRequest.getPhone();
        Long id = updatePhoneRequest.getId();
        ThrowUtils.throwIf(phone==null||code==null||id==null,ErrorCode.PARAMS_ERROR);
        //查看该电话是否被注册
        User userByPhone = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phone));
        ThrowUtils.throwIf(userByPhone!=null&&!userByPhone.getId().equals(id),new bizException(-1,"该手机号已被注册"));
        //验证码是否正确
        String Pcode = (String) redisTemplate.opsForValue().get(phone);
        ThrowUtils.throwIf(code==null,new bizException(-3,"未获取验证码"));
        ThrowUtils.throwIf(!code.equals(Pcode),new bizException(-4,"验证码错误"));
        User user = userService.getById(id);
        user.setPhone(phone);
        boolean b = userService.updateById(user);
        ThrowUtils.throwIf(!b,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }
    @PostMapping("update/password")
    @ApiOperation("修改密码")
    public BaseResponse<Boolean> updatePassword(@RequestBody UpdatePasswordRequest updatePasswordRequest) {
        long id = updatePasswordRequest.getId();
        String phone = updatePasswordRequest.getPhone();
        String code = updatePasswordRequest.getCode();
        String password = updatePasswordRequest.getNewPassword();
        ThrowUtils.throwIf(phone==null||code==null||password==null,ErrorCode.PARAMS_ERROR);
        //验证码是否正确
        String Pcode = (String) redisTemplate.opsForValue().get(phone);
        ThrowUtils.throwIf(Pcode==null,new bizException(-3,"未获取验证码"));
        ThrowUtils.throwIf(!code.equals(Pcode),new bizException(-4,"验证码错误"));
        User user = userService.getById(id);
        user.setUserPassword(userService.getPwd(password));
        boolean b = userService.updateById(user);
        ThrowUtils.throwIf(!b,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }
    @PostMapping("list/page/vo")
    @ApiOperation("分页查询用户")
    public BaseResponse<Page<UserVO>> getAllUser(@RequestBody UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest==null,ErrorCode.PARAMS_ERROR);
        int current = userQueryRequest.getCurrent();
        int pageSize = userQueryRequest.getPageSize();
        Page<User> userPage=new Page<>(current,pageSize);
        QueryWrapper<User> queryWrapper = userService.getQueryWrapper(userQueryRequest);
        userPage=userService.page(userPage,queryWrapper);
        //将userPage转换为UserVoPage
        Page<UserVO> userVOPage=new Page<>(current,pageSize,userPage.getTotal());
        //将user转换为uservo
        List<User> records = userPage.getRecords();
        List<UserVO> userVOList = userService.getUserVOList(records);
        userVOPage.setRecords(userVOList);
        return ResultUtils.success(userVOPage);
    }
    @GetMapping("get/code")
    @ApiOperation("获取验证码")
    public BaseResponse<String> getCode(String phone){
        String code = userService.getCode(phone);
        return ResultUtils.success("发送验证码成功");
    }
}
